#include "zen_macro.h"

#if ZEN_OS_IOS
#include "zen_utils_ios.h"

namespace Zen {

	class UtilsIOS__ : public UtilsIOS
	{
	public:
		NSString* DocumentPath(NSString* path) override
		{
			NSString *home= [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];
			return [home stringByAppendingPathComponent:path];
		}
		
		NSString * ResourcePath(NSString* path) override
		{
			return [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:path];
		}
		
		NSString * ToNSString(std::string const & s) override
		{
			return [NSString stringWithUTF8String:s.data()];
		}
		
		std::string ToString(NSString * s) override
		{
			return [s UTF8String];
		}
		
		std::string GetAppID() override
		{
			return [[[NSBundle mainBundle] bundleIdentifier] UTF8String];
		}
		std::string GetDeviceID() override
		{
			return [[[UIDevice currentDevice] identifierForVendor] UUIDString].UTF8String;
		}
		
		std::string GetDocumentPath(std::string const & path) override {
			return ToString(DocumentPath(ToNSString(path)));
		}
		
		bool IsResourceExist(std::string const & path) override
		{
			NSFileManager * manager = [NSFileManager defaultManager];
			return [manager fileExistsAtPath:ResourcePath(ToNSString(path))];
		}

		bool IsDocumentExist(std::string const & path) override
		{
			NSFileManager * manager = [NSFileManager defaultManager];
			return [manager fileExistsAtPath:DocumentPath(ToNSString(path))];
		}

		std::vector<uint8_t> LoadResource(std::string const & path) override
		{
			auto value = [NSData dataWithContentsOfFile:ResourcePath(ToNSString(path))];
			if(value == nil) return {};

			auto bytes = (uint8_t const*)value.bytes;
			auto size = value.length;
			return std::vector<uint8_t>(bytes + 0, bytes + size);
		}

		std::vector<uint8_t> LoadDocument(std::string const & path) override
		{
			auto value = [NSData dataWithContentsOfFile:DocumentPath(ToNSString(path))];
			if(value == nil) return {};

			auto bytes = (uint8_t const*)value.bytes;
			auto size = value.length;
			return std::vector<uint8_t>(bytes + 0, bytes + size);
		}

		bool SaveDocument(std::string const & path, void const * value, size_t size) override
		{
			NSData * ocd = [NSData dataWithBytes:value length:size];
			return [ocd writeToFile:DocumentPath(ToNSString(path)) atomically:YES];
		}

		std::vector<uint8_t> LoadURL(std::string const & url) override
		{
			auto content = [NSData dataWithContentsOfURL:[NSURL URLWithString:[NSString stringWithUTF8String:url.data()]]];
			if(content == nil) return {};

			auto value = (uint8_t const *)content.bytes;
			auto size = content.length;
			return std::vector<uint8_t>(value, value + size);
		}

		std::string GetSystemLanguage() override
		{
			NSUserDefaults * defaults = [NSUserDefaults standardUserDefaults];

			NSArray * allLanguages = [defaults objectForKey:@"AppleLanguages"];

			NSString * preferredLang = [allLanguages objectAtIndex:0];

			NSLog(@"current lang:%@", preferredLang);

			if(!preferredLang) return "";
			return [preferredLang UTF8String];
		}
		static UtilsIOS__ * Instance()
		{
			static auto me = new UtilsIOS__;
			return me;
		}
	};

	Utils * Utils::Instance()
	{
		return UtilsIOS__::Instance();
	}
	UtilsIOS * UtilsIOS::Instance()
	{
		return UtilsIOS__::Instance();
	}
}

#endif
